using CodingBlog.Core.Model;
using CodingBlog.Core.Repository;

using NUnit.Framework;

namespace CodingBlog.Core.Tests.Repository
{
    [TestFixture]
    internal class UserRepositoryTests : BaseRepositoryTest
    {
        private User GetSampleUser(string name, string email, string password)
        {
            return new User
            {
                Name = name,
                Email = email,
                Password = password
            };
        }

        [Test]
        public void should_be_able_to_add_and_read_user_from_database()
        {
            var userRepository = new UserRepository();

            var userName = "Test User";
            var userEmail = "test@test.com";
            var userPassword = "secret_password";
            var userToBeCreated = GetSampleUser(userName, userEmail, userPassword);

            var userCreated = userRepository.CreateUser(userToBeCreated);
            var userToTest = userRepository.GetUserById(userCreated.Id);

            Assert.NotNull(userToTest);
            Assert.AreEqual(userName, userToTest.Name);
            Assert.AreEqual(userEmail, userToTest.Email);
            Assert.AreEqual(userPassword, userToTest.Password);
            Assert.GreaterOrEqual(userToTest.Id, 1);
        }

        [TestCase("exists_email@codingblog.com", Result = true)]
        [TestCase("not_exists_email@codingblog.com", Result = false)]
        public bool can_check_if_user_with_given_email_exists(string emailToBeChecked)
        {
            var email = "exists_email@codingblog.com";
            var userName = "Test User";
            var userPassword = "secret_password";
            var userToBeCreated = GetSampleUser(userName, email, userPassword);

            var userRepository = new UserRepository();
            userRepository.CreateUser(userToBeCreated);

            return userRepository.EmailIsInUse(emailToBeChecked);
        }

        [Test]
        public void when_user_provides_valid_credentials_he_is_fetched_from_db()
        {
            var userRepository = new UserRepository();

            var userName = "Test User";
            var userEmail = "test@test.com";
            var userPassword = "secret_password";
            var userToBeCreated = GetSampleUser(userName, userEmail, userPassword);

            userRepository.CreateUser(userToBeCreated);

            var authenticatedUser = userRepository.GetUserByEmailAndPassword(userEmail, userPassword);

            Assert.NotNull(authenticatedUser);
            Assert.AreEqual(userName, authenticatedUser.Name);
            Assert.AreEqual(userEmail, authenticatedUser.Email);
            Assert.AreEqual(userPassword, authenticatedUser.Password);
        }

        [TestCase("incorrect@email.com", "secret_password")]
        [TestCase("test@test.com", "incorrect_password")]
        [TestCase("incorrect@email.com", "incorrect_password")]
        public void when_user_provides_incorrect_credentials_he_is_null(string email, string password)
        {
            var userRepository = new UserRepository();

            var userName = "Test User";
            var userEmail = "test@test.com";
            var userPassword = "secret_password";
            var userToBeCreated = GetSampleUser(userName, userEmail, userPassword);

            userRepository.CreateUser(userToBeCreated);

            var authenticatedUser = userRepository.GetUserByEmailAndPassword(email, password);

            Assert.Null(authenticatedUser);
        }
    }
}
